﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 复选框控件
    /// </summary>
    [Description("复选框控件")]
    [DefaultProperty("Checked")]
    [DefaultEvent("CheckedChanged")]
    [TypeConverter(typeof(PropertyOrderConverter))]
    [Designer(typeof(CheckBoxPlusDesigner))]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(CheckBoxPlus), "Controls.CheckBoxPlus.Resources.CheckBoxPlus.bmp")]
    public class CheckBoxPlus : DpiControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(CheckBoxPlus)).GetName().Name, typeof(CheckBoxPlus).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled= SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        private static readonly object EventCheckedChanged = new object();
        /// <summary>
        /// 控件Checked状态更改事件
        /// </summary>
        [Description("控件Checked状态更改事件")]
        public event EventHandler CheckedChanged
        {
            add { Events.AddHandler(EventCheckedChanged, value); }
            remove { Events.RemoveHandler(EventCheckedChanged, value); }
        }

        private static readonly object EventCheckStateChanged = new object();
        /// <summary>
        /// 控件CheckState状态更改事件
        /// </summary>
        [Description("控件CheckState状态更改事件")]
        public event EventHandler CheckStateChanged
        {
            add { Events.AddHandler(EventCheckStateChanged, value); }
            remove { Events.RemoveHandler(EventCheckStateChanged, value); }
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackColorChanged
        {
            add { base.BackColorChanged += value; }
            remove { base.BackColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        #endregion

        #region 新增属性

        private CheckBoxPlusStylePattern stylePattern = CheckBoxPlusStylePattern.Box;
        /// <summary>
        /// 显示风格 是按正常Check复选框风格显示，还是按Button按钮风格显示
        /// </summary>
        [Description("显示风格 是按正常Check复选框风格显示，还是按Button按钮风格显示")]
        [Category("杂项")]
        [PropertyOrder(-195)]
        [DefaultValue(CheckBoxPlusStylePattern.Box)]
        public CheckBoxPlusStylePattern StylePattern
        {
            get { return this.stylePattern; }
            set
            {
                if (this.stylePattern == value)
                    return;

                this.stylePattern = value;
                this.AdjustSize();
            }
        }

        private BoxPatternObject boxPattern;
        /// <summary>
        /// 复选框模式
        /// </summary>
        [Description("复选框模式")]
        [PropertyOrder(-194)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public BoxPatternObject BoxPattern
        {
            get
            {
                if (this.boxPattern == null)
                    this.boxPattern = new BoxPatternObject(this);
                return this.boxPattern;
            }
        }

        private ButtonPatternObject buttonPattern;
        /// <summary>
        /// Button模式
        /// </summary>
        [Description("Button模式")]
        [PropertyOrder(-193)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ButtonPatternObject ButtonPattern
        {
            get
            {
                if (this.buttonPattern == null)
                    this.buttonPattern = new ButtonPatternObject(this);
                return this.buttonPattern;
            }
        }

        private bool threeState = false;
        /// <summary>
        /// 控件是否为三种选择状态（否则为两种选择状态）
        /// </summary>
        [Description("控件是否为三种选择状态（否则为两种选择状态）")]
        [Category("杂项")]
        [PropertyOrder(-192)]
        [DefaultValue(false)]
        public bool ThreeState
        {
            get { return this.threeState; }
            set
            {
                if (this.threeState == value)
                    return;

                this.threeState = value;
                this.Invalidate();
            }
        }

        private CheckState checkState = CheckState.Unchecked;
        /// <summary>
        /// 选中状态
        /// </summary>
        [Description("选中状态")]
        [Category("杂项")]
        [PropertyOrder(-191)]
        [DefaultValue(CheckState.Unchecked)]
        [Bindable(true)]
        public CheckState CheckState
        {
            get { return this.checkState; }
            set
            {
                if (this.checkState == value)
                    return;

                this.checkState = value;
                this.Invalidate();

                if (!this.DesignMode)
                {
                    this.OnCheckStateChanged(EventArgs.Empty);
                }
            }
        }

        private bool autoCheck = true;
        /// <summary>
        /// 单击时是否自动更改控件状态
        /// </summary>
        [Description("单击时是否自动更改控件状态")]
        [Category("杂项")]
        [PropertyOrder(-190)]
        [DefaultValue(true)]
        public bool AutoCheck
        {
            get { return this.autoCheck; }
            set
            {
                if (this.autoCheck == value)
                    return;

                this.autoCheck = value;
            }
        }

        private bool _checked = false;
        /// <summary>
        /// 是否已选中
        /// </summary>
        [Description("是否已选中")]
        [Category("杂项")]
        [PropertyOrder(-189)]
        [DefaultValue(false)]
        [Bindable(true)]
        public bool Checked
        {
            get { return this._checked; }
            set
            {
                if (this._checked == value)
                    return;

                this._checked = value;
                this.Invalidate();

                if (!this.DesignMode)
                {
                    this.OnCheckedChanged(EventArgs.Empty);
                }
            }
        }

        internal ImageList imageList;
        /// <summary>
        /// 获取在控件上显示的图像的ImageList
        /// </summary>
        [Description("获取在控件上显示的图像的ImageList ")]
        [PropertyOrder(-120)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.Repaint)]
        public ImageList ImageList
        {
            get
            {
                return this.imageList;
            }
            set
            {
                if (imageList == value)
                    return;

                EventHandler recreateHandler = new EventHandler(this.RecreateImageListHandler);
                EventHandler disposedHandler = new EventHandler(this.DetachImageListHandler);

                if (this.imageList != null)
                {
                    this.imageList.RecreateHandle -= recreateHandler;
                    this.imageList.Disposed -= disposedHandler;
                }

                this.imageList = value;
                this.StyleAppearance.BoxPattern.UnChecked.Normal.imageIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.BoxPattern.UnChecked.Disabled.imageIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.BoxPattern.Indeterminate.Normal.imageIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.BoxPattern.Indeterminate.Disabled.imageIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.BoxPattern.Checked.Normal.imageIndexer.SyncIndexer(value);//同步索引管理器
                this.StyleAppearance.BoxPattern.Checked.Disabled.imageIndexer.SyncIndexer(value);//同步索引管理器

                if (value != null)
                {
                    this.imageList.RecreateHandle += recreateHandler;
                    this.imageList.Disposed += disposedHandler;
                }
                this.Invalidate();
            }
        }

        /// <summary>
        /// 鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool IsMouseEnter
        {
            get { return this.mouseenterobject == this; }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(106, 20); }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        /// <summary>
        /// 否根据内容自动调整控件的大小。
        /// </summary>
        [Description("否根据内容自动调整控件的大小")]
        [Browsable(true)]
        [DefaultValue(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [EditorBrowsable(EditorBrowsableState.Always)]
        [RefreshProperties(RefreshProperties.All)]
        public override bool AutoSize
        {
            get { return base.AutoSize; }
            set
            {
                if (base.AutoSize == value)
                    return;

                this.autoing = true;
                if (value)
                {
                    int saveWidth = this.requestedWidth;
                    int saveHeight = this.requestedHeight;
                    base.AutoSize = value;
                    try
                    {
                        Size preferredSize = (AutoSize) ? PreferredSize : new Size(this.requestedWidth, this.requestedHeight);
                        this.SetBoundsCore(this.Location.X, this.Location.Y, preferredSize.Width, preferredSize.Height, BoundsSpecified.Size);
                    }
                    finally
                    {
                        this.requestedWidth = saveWidth;
                        this.requestedHeight = saveHeight;
                    }
                }
                else
                {
                    base.AutoSize = value;
                    this.SetBoundsCore(this.Location.X, this.Location.Y, this.requestedWidth, this.requestedHeight, BoundsSpecified.Size);
                }
                this.autoing = false;
            }
        }

        /// <summary>
        /// 内边距限于AutoSize
        /// </summary>
        [Description("内边距限于AutoSize")]
        public new Padding Padding
        {
            get { return base.Padding; }
            set
            {
                if (base.Padding == value)
                    return;

                base.Padding = value;
                this.AdjustSize();
            }

        }

        public override Font Font
        {
            get { return base.Font; }
            set
            {
                if (base.Font == value)
                    return;

                base.Font = value;
                this.AdjustSize();
            }
        }

        public override string Text
        {
            get { return base.Text; }
            set
            {
                if (base.Text == value)
                    return;

                base.Text = value;
                this.AdjustSize();
            }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color BackColor
        {
            get
            {
                if (this.StylePattern == CheckBoxPlusStylePattern.Box)
                {
                    return this.StyleAppearance.BoxPattern.BackColor;
                }
                else
                {
                    if ((this.ThreeState && this.CheckState == CheckState.Checked) || (!this.ThreeState && this.Checked))
                    {
                        return this.StyleAppearance.ButtonPattern.Checked.Normal.BackColor;
                    }
                    else if ((this.ThreeState && this.CheckState == CheckState.Indeterminate))
                    {
                        return this.StyleAppearance.ButtonPattern.Indeterminate.Normal.BackColor;
                    }
                    else
                    {
                        return this.StyleAppearance.ButtonPattern.UnChecked.Normal.BackColor;
                    }
                }
            }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get
            {
                if (this.StylePattern == CheckBoxPlusStylePattern.Box)
                {
                    return this.StyleAppearance.BoxPattern.UnChecked.Normal.TextColor;
                }
                else
                {
                    if ((this.ThreeState && this.CheckState == CheckState.Checked) || (!this.ThreeState && this.Checked))
                    {
                        return this.StyleAppearance.ButtonPattern.Checked.Normal.TextColor;
                    }
                    else if ((this.ThreeState && this.CheckState == CheckState.Indeterminate))
                    {
                        return this.StyleAppearance.ButtonPattern.Indeterminate.Normal.TextColor;
                    }
                    else
                    {
                        return this.StyleAppearance.ButtonPattern.UnChecked.Normal.TextColor;
                    }
                }
            }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 鼠标按下类型
        /// </summary>
        private MouseButtons mousedowntype = MouseButtons.None;
        /// <summary>
        /// 鼠标已进入对象
        /// </summary>
        private object mouseenterobject = null;

        /// <summary>
        /// 复选框rect
        /// </summary>
        private RectangleF check_rect;
        /// <summary>
        /// 文本rect
        /// </summary>
        private RectangleF text_rect;

        /// <summary>
        /// 控件要求Width
        /// </summary>
        private int requestedWidth;
        /// <summary>
        /// 控件要求Height
        /// </summary>
        private int requestedHeight;
        /// <summary>
        /// AutoSize切换中
        /// </summary>
        private bool autoing = false;

        #endregion

        public CheckBoxPlus()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);//自定义单击事件逻辑
            SetStyle(ControlStyles.StandardDoubleClick, false);//停用双加事件

            this.SuspendLayout();
            this.requestedWidth = this.Width;
            this.requestedHeight = this.Height;
            this.AutoSize = true;
            this.OnSkinChanged();
            this.ResumeLayout();
        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.AdjustSize();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Graphics g = e.Graphics;
            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);

            if (this.StylePattern == CheckBoxPlusStylePattern.Box)
            {
                int scale_checkSize = (int)Math.Ceiling(this.BoxPattern.BoxSize * this.ScaleDpi);

                Color border_color = Color.Empty;
                Color back_color = Color.Empty;
                Color fore_color = Color.Empty;
                Color text_color = Color.Empty;

                StyleAppearanceObject.BoxPatternAppearanceObject.StateAppearanceObject checkModelStateAppearance = null;
                Image image_normal_tmp = null;
                Image image_disabled_tmp = null;
                if ((this.ThreeState == false && this.Checked) || (this.ThreeState == true && this.CheckState == CheckState.Checked))
                {
                    checkModelStateAppearance = (this.StyleAppearance.BoxPattern.Checked);
                    image_normal_tmp = this.StyleAppearance.BoxPattern.Checked.Normal.Image;
                    image_disabled_tmp = this.StyleAppearance.BoxPattern.Checked.Disabled.Image;
                }
                else if (this.ThreeState == true && this.CheckState == CheckState.Indeterminate)
                {
                    checkModelStateAppearance = (this.StyleAppearance.BoxPattern.Indeterminate);
                    image_normal_tmp = this.StyleAppearance.BoxPattern.Indeterminate.Normal.Image;
                    image_disabled_tmp = this.StyleAppearance.BoxPattern.Indeterminate.Disabled.Image;
                }
                else
                {
                    checkModelStateAppearance = (this.StyleAppearance.BoxPattern.UnChecked);
                    image_normal_tmp = this.StyleAppearance.BoxPattern.UnChecked.Normal.Image;
                    image_disabled_tmp = this.StyleAppearance.BoxPattern.UnChecked.Disabled.Image;
                }

                if (!this.Enabled)
                {
                    border_color = checkModelStateAppearance.Disabled.BoxBorderColor;
                    back_color = checkModelStateAppearance.Disabled.BoxBackColor;
                    fore_color = checkModelStateAppearance.Disabled.BoxForeColor;
                    text_color = checkModelStateAppearance.Disabled.TextColor;
                }
                else
                {
                    border_color = checkModelStateAppearance.Normal.BoxBorderColor;
                    back_color = checkModelStateAppearance.Normal.BoxBackColor;
                    fore_color = checkModelStateAppearance.Normal.BoxForeColor;
                    text_color = checkModelStateAppearance.Normal.TextColor;
                }

                // 默认
                if (this.BoxPattern.BoxDrawMode == CheckBoxPlusBoxDrawMode.Default)
                {
                    // 背景
                    SolidBrush check_back_sb = new SolidBrush(back_color);
                    g.FillRectangle(check_back_sb, this.check_rect);
                    check_back_sb.Dispose();

                    // 边框
                    Pen check_border_pen = new Pen(border_color, 1);
                    g.DrawRectangle(check_border_pen, this.check_rect.X, this.check_rect.Y, this.check_rect.Width - 1, this.check_rect.Height - 1);
                    check_border_pen.Dispose();

                    if ((this.ThreeState == false && this.Checked) || (this.ThreeState == true && this.CheckState == CheckState.Checked))
                    {
                        float min_grid = scale_checkSize / 10f;
                        PointF[] check_char_line = new PointF[] {
                        new PointF(this.check_rect.X+min_grid,this.check_rect.Y+ min_grid * 4.5f),
                        new PointF(this.check_rect.X+min_grid *4,this.check_rect.Y+  min_grid * 7),
                        new PointF(this.check_rect.X+min_grid*8f ,this.check_rect.Y+  min_grid*2)
                        };

                        g.SmoothingMode = SmoothingMode.AntiAlias;

                        Pen check_fore_pen = new Pen(fore_color, scale_checkSize / 7f);
                        g.DrawLines(check_fore_pen, check_char_line);
                        check_fore_pen.Dispose();

                        g.SmoothingMode = SmoothingMode.Default;
                    }
                    else if (this.ThreeState == true && this.CheckState == CheckState.Indeterminate)
                    {
                        int min_grid = (int)Math.Ceiling(scale_checkSize / 10f) * 2;
                        RectangleF check_char_rect = new RectangleF(this.check_rect.X + min_grid, this.check_rect.Y + min_grid, this.check_rect.Width - min_grid * 2, this.check_rect.Height - min_grid * 2);
                        SolidBrush check_char_sb = new SolidBrush(fore_color);
                        g.FillRectangle(check_char_sb, check_char_rect);
                        check_char_sb.Dispose();

                    }
                }
                // 自定义图片
                else
                {
                    g.DrawImage(this.Enabled ? image_normal_tmp : image_disabled_tmp, this.check_rect);
                }

                // 文本
                SolidBrush text_sb = new SolidBrush(text_color);
                g.DrawString(this.Text, this.Font, text_sb, this.text_rect.X, this.text_rect.Y, StringFormat.GenericTypographic);
                text_sb.Dispose();

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    Pen activate_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawRectangle(activate_pen, this.text_rect.X, this.text_rect.Y, this.text_rect.Width, this.text_rect.Height);
                    activate_pen.Dispose();
                }
            }
            else
            {
                Color border_color = Color.Empty;
                Color back_color = Color.Empty;
                Color text_color = Color.Empty;

                StyleAppearanceObject.ButtonPatternAppearanceObject.StateAppearanceObject buttonModelStateAppearance = (this.StyleAppearance.ButtonPattern.UnChecked);
                if ((this.ThreeState == false && this.Checked) || (this.ThreeState == true && this.CheckState == CheckState.Checked))
                {
                    buttonModelStateAppearance = (this.StyleAppearance.ButtonPattern.Checked);
                }
                else if (this.ThreeState == true && this.CheckState == CheckState.Indeterminate)
                {
                    buttonModelStateAppearance = (this.StyleAppearance.ButtonPattern.Indeterminate);
                }

                if (!this.Enabled)
                {
                    border_color = buttonModelStateAppearance.Disabled.BorderColor;
                    back_color = buttonModelStateAppearance.Disabled.BackColor;
                    text_color = buttonModelStateAppearance.Disabled.TextColor;
                }
                else if (this.mouseenterobject == this)
                {
                    border_color = buttonModelStateAppearance.Enter.BorderColor;
                    back_color = buttonModelStateAppearance.Enter.BackColor;
                    text_color = buttonModelStateAppearance.Enter.TextColor;
                }
                else
                {
                    border_color = buttonModelStateAppearance.Normal.BorderColor;
                    back_color = buttonModelStateAppearance.Normal.BackColor;
                    text_color = buttonModelStateAppearance.Normal.TextColor;
                }

                SolidBrush back_sb = new SolidBrush(back_color);
                g.FillRectangle(back_sb, this.ClientRectangle);
                back_sb.Dispose();

                Size text_size = Size.Ceiling(g.MeasureString(this.Text, this.Font, int.MaxValue, StringFormat.GenericTypographic));
                SolidBrush text_sb = new SolidBrush(text_color);
                g.DrawString(this.Text, this.Font, text_sb, (this.ClientRectangle.X + (this.ClientRectangle.Width - text_size.Width) / 2), (this.ClientRectangle.Y + (this.ClientRectangle.Height - font_metrics.GetFontRealHeight()) / 2), StringFormat.GenericTypographic);
                text_sb.Dispose();

                if (this.ButtonPattern.BorderVisible)
                {
                    Pen border_pen = new Pen(border_color);
                    g.DrawRectangle(border_pen, new Rectangle(this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1));
                    border_pen.Dispose();
                }

                //控件激活状态虚线框
                if (this.Focused && this.ShowFocusCues)
                {
                    Pen activate_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot };
                    g.DrawRectangle(activate_pen, this.ClientRectangle.X + 3, this.ClientRectangle.Y + 3, this.ClientRectangle.Width - 7, this.ClientRectangle.Height - 7);
                    activate_pen.Dispose();
                }
            }
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            this.mousedowntype = MouseButtons.None;
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!this.Enabled)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (!this.Visible)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.Parent == null)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            Point point = this.PointToClient(Control.MousePosition);
            base.OnMouseEnter(e);

            if (this.StylePattern == CheckBoxPlusStylePattern.Button)
            {
                this.mouseenterobject = this;
                this.Invalidate();
            }
            else
            {
                if (this.IsInArea(point))
                {
                    this.mouseenterobject = this;
                    this.Invalidate();
                }
            }
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.mouseenterobject = null;
            this.Invalidate();
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this.StylePattern == CheckBoxPlusStylePattern.Box)
            {
                object mouseEmter_tmp = this.IsInArea(e.Location) ? this : null;
                if (this.mouseenterobject != mouseEmter_tmp)
                {
                    this.mouseenterobject = mouseEmter_tmp;
                    this.Invalidate();
                }
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (this.IsInArea(e.Location))
            {
                if (!this.Focused)
                {
                    this.Focus();
                }

                this.mousedowntype |= e.Button;
            }

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.mousedowntype.HasFlag(MouseButtons.Left))
                {
                    if (this.IsInArea(e.Location))
                    {
                        this.OnClick(e);
                        this.OnMouseClick(e);
                        if (this.AutoCheck)
                        {
                            this.SetState();
                        }
                    }
                }
            }
            this.mousedowntype &= ~e.Button;

            base.OnMouseUp(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.Space:
                    {
                        this.OnClick(EventArgs.Empty);
                        break;
                    }
            }

            base.OnKeyUp(e);
        }

        public override Size GetPreferredSize(Size proposedSize)
        {
            if (this.AutoSize)
            {
                Padding scale_padding = new Padding((int)Math.Ceiling(this.Padding.Left * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Top * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Right * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Bottom * this.ScaleDpi));
                int scale_checkSize = (int)Math.Ceiling(this.BoxPattern.BoxSize * this.ScaleDpi);
                int scale_checkTextSpace = (int)Math.Ceiling(this.BoxPattern.TextDistance * this.ScaleDpi);

                Size scale_check_size = new Size(scale_checkSize, scale_checkSize);
                Size scale_text_size = this.GetTextSize();
                Size size = Size.Empty;
                int text_border = 2;

                switch (this.BoxPattern.BoxAlignment)
                {
                    case CheckBoxPlusBoxAlignment.Top:
                    case CheckBoxPlusBoxAlignment.Center:
                    case CheckBoxPlusBoxAlignment.Bottom:
                        {
                            size = new Size(Math.Max(scale_check_size.Width, scale_text_size.Width) + scale_padding.Left + scale_padding.Right + text_border * 2, scale_check_size.Height + scale_checkTextSpace + scale_text_size.Height + scale_padding.Top + scale_padding.Bottom + text_border * 2);
                            break;
                        }
                    case CheckBoxPlusBoxAlignment.Left:
                    case CheckBoxPlusBoxAlignment.Right:
                        {
                            size = new Size(scale_check_size.Width + scale_checkTextSpace + scale_text_size.Width + scale_padding.Left + scale_padding.Right + text_border * 2, Math.Max(scale_check_size.Height, scale_text_size.Height) + scale_padding.Top + scale_padding.Bottom + text_border * 2);
                            break;
                        }
                }
                proposedSize = size;
                return size;
            }
            else
            {
                return base.GetPreferredSize(proposedSize);
            }
        }

        protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
        {
            if (!this.autoing)
            {
                requestedHeight = height;
                requestedWidth = width;
            }

            if (this.AutoSize)
            {
                Size preferredSize = this.PreferredSize;
                width = preferredSize.Width;
                height = preferredSize.Height;
            }

            base.SetBoundsCore(x, y, width, height, specified);

            this.InitializeElement();
            this.Invalidate();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.imageList != null)
                {
                    this.imageList.RecreateHandle -= new EventHandler(this.RecreateImageListHandler);
                    this.imageList.Disposed -= new EventHandler(this.DetachImageListHandler);
                    this.imageList = null;
                }
            }
            base.Dispose(disposing);
        }

        #endregion

        #region 虚方法

        protected virtual void OnCheckedChanged(EventArgs e)
        {
            EventHandler handler = Events[EventCheckedChanged] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnCheckStateChanged(EventArgs e)
        {
            EventHandler handler = Events[EventCheckStateChanged] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {
            NativeMethods.TEXTMETRIC font_metrics = ControlHelper.GetFontMetrics(this.Handle, this.Font);
            Padding scale_padding = new Padding((int)Math.Ceiling(this.Padding.Left * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Top * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Right * this.ScaleDpi), (int)Math.Ceiling(this.Padding.Bottom * this.ScaleDpi));
            int scale_checkSize = (int)Math.Ceiling(this.BoxPattern.BoxSize * this.ScaleDpi);
            int scale_checkTextSpace = (int)Math.Ceiling(this.BoxPattern.TextDistance * this.ScaleDpi);

            Rectangle scale_rectf = this.AutoSize ? new Rectangle(this.ClientRectangle.X + scale_padding.Left, this.ClientRectangle.Y + scale_padding.Top, this.ClientRectangle.Width - scale_padding.Left - scale_padding.Right, this.ClientRectangle.Height - scale_padding.Top - scale_padding.Bottom) : this.ClientRectangle;
            Size scale_check_size = new Size(scale_checkSize, scale_checkSize);
            Size scale_text_size = this.GetTextSize();

            switch (this.BoxPattern.BoxAlignment)
            {
                case CheckBoxPlusBoxAlignment.Top:
                    {
                        this.check_rect = new RectangleF(
                           scale_rectf.X + (scale_rectf.Width - scale_check_size.Width) / 2,
                           scale_rectf.Y,
                           scale_check_size.Width,
                           scale_check_size.Height);

                        this.text_rect = new RectangleF(
                                 scale_rectf.X + (scale_rectf.Width - scale_text_size.Width) / 2,
                                 this.check_rect.Bottom + scale_checkTextSpace,
                                 scale_text_size.Width,
                                 scale_text_size.Height);

                        break;
                    }
                case CheckBoxPlusBoxAlignment.Center:
                    {
                        this.check_rect = new RectangleF(
                           scale_rectf.X + (scale_rectf.Width - scale_check_size.Width) / 2,
                           scale_rectf.Y + (scale_rectf.Height - scale_check_size.Height - scale_checkTextSpace - scale_text_size.Height) / 2,
                           scale_check_size.Width,
                           scale_check_size.Height);

                        this.text_rect = new RectangleF(
                                  scale_rectf.X + (scale_rectf.Width - scale_text_size.Width) / 2,
                                  this.check_rect.Bottom + scale_checkTextSpace,
                                  scale_text_size.Width,
                                  scale_text_size.Height);

                        break;
                    }
                case CheckBoxPlusBoxAlignment.Bottom:
                    {
                        this.check_rect = new RectangleF(
                           scale_rectf.X + (scale_rectf.Width - scale_check_size.Width) / 2,
                           scale_rectf.Bottom - scale_check_size.Height,
                           scale_check_size.Width,
                           scale_check_size.Height);

                        this.text_rect = new RectangleF(
                           scale_rectf.X + (scale_rectf.Width - scale_text_size.Width) / 2,
                           this.check_rect.Y - scale_checkTextSpace - scale_text_size.Height,
                           scale_text_size.Width,
                           scale_text_size.Height);
                        break;
                    }
                case CheckBoxPlusBoxAlignment.Left:
                    {
                        this.check_rect = new RectangleF(
                           scale_rectf.X,
                           scale_rectf.Y + (scale_rectf.Height - scale_check_size.Height) / 2,
                           scale_check_size.Width,
                           scale_check_size.Height);

                        this.text_rect = new RectangleF(
                               this.check_rect.Right + scale_checkTextSpace,
                               scale_rectf.Y + (scale_rectf.Height - font_metrics.GetFontRealHeight()) / 2,
                               scale_text_size.Width,
                               scale_text_size.Height);

                        break;
                    }
                case CheckBoxPlusBoxAlignment.Right:
                    {
                        this.check_rect = new RectangleF(
                           scale_rectf.Right - scale_check_size.Width,
                           scale_rectf.Y + (scale_rectf.Height - scale_check_size.Height) / 2,
                           scale_check_size.Width,
                           scale_check_size.Height);

                        this.text_rect = new RectangleF(
                           this.check_rect.X - scale_checkTextSpace - scale_text_size.Width,
                           scale_rectf.Y + (scale_rectf.Height - font_metrics.GetFontRealHeight()) / 2,
                           scale_text_size.Width,
                           scale_text_size.Height);
                        break;
                    }
            }
        }

        #endregion 

        #region 私有方法

        /// <summary>
        /// 更新控件size
        /// </summary>
        private void AdjustSize()
        {
            Size preferredSize = (this.AutoSize) ? this.PreferredSize : new Size(this.requestedWidth, this.requestedHeight);
            this.SetBoundsCore(this.Location.X, this.Location.Y, preferredSize.Width, preferredSize.Height, BoundsSpecified.Size);
        }

        /// <summary>
        /// 获取文本size
        /// </summary>
        /// <returns></returns>
        private Size GetTextSize()
        {
            IntPtr hDC = IntPtr.Zero;
            Graphics g = null;
            ControlHelper.GetWindowClientGraphics(this.Handle, out g, out hDC);

            Size text_size = Size.Ceiling(g.MeasureString(this.Text, this.Font, int.MaxValue, StringFormat.GenericTypographic));
            g.Dispose();
            NativeMethods.ReleaseDC(this.Handle, hDC);

            return text_size;
        }

        /// <summary>
        /// 指定坐标是否在控件有效范围内
        /// </summary>
        /// <param name="point">指定坐标</param>
        /// <returns></returns>
        private bool IsInArea(Point point)
        {
            if (this.BoxPattern.OperateAreaScope == CheckBoxPlusBoxOperateAreaScope.All || this.StylePattern == CheckBoxPlusStylePattern.Button)
                return true;

            if (this.StylePattern == CheckBoxPlusStylePattern.Box)
            {
                if (
                    (this.BoxPattern.OperateAreaScope == CheckBoxPlusBoxOperateAreaScope.Box && this.check_rect.Contains(point)) ||
                    (this.BoxPattern.OperateAreaScope == CheckBoxPlusBoxOperateAreaScope.BoxText && (this.check_rect.Contains(point) || this.text_rect.Contains(point)))
                    )
                    return true;

            }

            return false;
        }

        /// <summary>
        /// 设置控件状态
        /// </summary>
        private void SetState()
        {
            if (this.ThreeState == false)
            {
                this.Checked = !this.Checked;
            }
            else
            {
                if (this.CheckState == CheckState.Unchecked)
                {
                    this.CheckState = CheckState.Indeterminate;
                }
                else if (this.CheckState == CheckState.Indeterminate)
                {
                    this.CheckState = CheckState.Checked;
                }
                else if (this.CheckState == CheckState.Checked)
                {
                    this.CheckState = CheckState.Unchecked;
                }
            }
        }

        /// <summary>
        /// ImageList更改后刷新控件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RecreateImageListHandler(object sender, EventArgs e)
        {
            if (this.IsHandleCreated)
            {
                this.Invalidate();
            }
        }

        /// <summary>
        /// ImageList释放时解绑清除清除引用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DetachImageListHandler(object sender, EventArgs e)
        {
            this.imageList = null;
        }

        #endregion

        #region 类

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class BoxPatternObject
        {
            private CheckBoxPlus owner = null;
            internal BoxPatternObject(CheckBoxPlus owner) { this.owner = owner; }

            #region  属性

            private CheckBoxPlusBoxAlignment boxAlignment = CheckBoxPlusBoxAlignment.Left;
            /// <summary>
            /// 复选框的对齐方式 
            /// </summary>
            [Description("复选框的对齐方式 ")]
            [PropertyOrder(-190)]
            [DefaultValue(CheckBoxPlusBoxAlignment.Left)]
            public CheckBoxPlusBoxAlignment BoxAlignment
            {
                get { return this.boxAlignment; }
                set
                {
                    if (this.boxAlignment == value)
                        return;

                    this.boxAlignment = value;
                    ((CheckBoxPlus)this.owner).AdjustSize();
                }
            }

            private int boxSize = 16;
            /// <summary>
            /// 复选框大小 
            /// </summary>
            [Description("复选框大小 ")]
            [PropertyOrder(-185)]
            [DefaultValue(16)]
            public int BoxSize
            {
                get { return this.boxSize; }
                set
                {
                    if (this.boxSize == value || value < 1)
                        return;

                    this.boxSize = value;
                    ((CheckBoxPlus)this.owner).AdjustSize();
                }
            }

            private CheckBoxPlusBoxDrawMode boxDrawMode = CheckBoxPlusBoxDrawMode.Default;
            /// <summary>
            /// 复选框的绘制模式
            /// </summary>
            [Description("复选框的绘制模式")]
            [PropertyOrder(-138)]
            [DefaultValue(CheckBoxPlusBoxDrawMode.Default)]
            public CheckBoxPlusBoxDrawMode BoxDrawMode
            {
                get { return this.boxDrawMode; }
                set
                {
                    if (this.boxDrawMode == value)
                        return;

                    this.boxDrawMode = value;
                    ((CheckBoxPlus)this.owner).AdjustSize();
                }
            }

            private int textDistance = 8;
            /// <summary>
            /// 复选框与文本的间距 
            /// </summary>
            [Description("复选框与文本的间距 ")]
            [PropertyOrder(-120)]
            [DefaultValue(8)]
            public int TextDistance
            {
                get { return this.textDistance; }
                set
                {
                    if (this.textDistance == value || value < 0)
                        return;

                    this.textDistance = value;
                    ((CheckBoxPlus)this.owner).AdjustSize();
                }
            }

            private CheckBoxPlusBoxOperateAreaScope operateAreaScope = CheckBoxPlusBoxOperateAreaScope.All;
            /// <summary>
            /// 鼠标操作有效范围 
            /// </summary>
            [Description("鼠标操作有效范围")]
            [PropertyOrder(-110)]
            [DefaultValue(CheckBoxPlusBoxOperateAreaScope.All)]
            public CheckBoxPlusBoxOperateAreaScope OperateAreaScope
            {
                get { return this.operateAreaScope; }
                set
                {
                    if (this.operateAreaScope == value)
                        return;

                    this.operateAreaScope = value;
                }
            }

            #endregion

        }

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class ButtonPatternObject
        {
            private CheckBoxPlus owner = null;
            internal ButtonPatternObject(CheckBoxPlus owner) { this.owner = owner; }

            #region 属性

            private bool borderVisible = true;
            /// <summary>
            /// 是否显示边框
            /// </summary>
            [Description("是否显示边框")]
            [PropertyOrder(-198)]
            [DefaultValue(true)]
            public bool BorderVisible
            {
                get { return this.borderVisible; }
                set
                {
                    if (this.borderVisible == value)
                        return;

                    this.borderVisible = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        #endregion

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinActivateColor = Color.Empty;
            private readonly Color defaultActivateColor = SystemColors.ControlText;
            private Color activateColor = Color.Empty;
            /// <summary>
            /// 控件激活的虚线框颜色
            /// </summary>
            [Description("控件激活的虚线框颜色")]
            [PropertyOrder(-200)]
            [SkinProperty(true, false)]
            public Color ActivateColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinActivateColor;
                    }

                    if (this.activateColor != Color.Empty)
                    {
                        return this.activateColor;
                    }

                    return this.defaultActivateColor;
                }
                set
                {
                    if (this.activateColor == value)
                        return;

                    this.activateColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeActivateColor()
            {
                return this.activateColor != Color.Empty;
            }
            private void ResetActivateColor()
            {
                this.activateColor = Color.Empty;
                this.Invalidate();
            }

            private BoxPatternAppearanceObject boxPattern;
            /// <summary>
            /// 单选框模式
            /// </summary>
            [Description("单选框模式")]
            [PropertyOrder(-193)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public BoxPatternAppearanceObject BoxPattern
            {
                get
                {
                    if (this.boxPattern == null)
                        this.boxPattern = new BoxPatternAppearanceObject(this.owner, this);
                    return this.boxPattern;
                }
            }

            private ButtonPatternAppearanceObject buttonPattern;
            /// <summary>
            /// 按钮模式
            /// </summary>
            [Description("按钮模式")]
            [PropertyOrder(-190)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public ButtonPatternAppearanceObject ButtonPattern
            {
                get
                {
                    if (this.buttonPattern == null)
                        this.buttonPattern = new ButtonPatternAppearanceObject(this.owner, this);
                    return this.buttonPattern;
                }
            }

            #endregion

            public class BoxPatternAppearanceObject : AppearanceObjectBase
            {
                internal BoxPatternAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

                #region 属性

                private Color skinBackColor = Color.Empty;
                private readonly Color defaultBackColor = SystemColors.Control;
                private Color backColor = Color.Empty;
                /// <summary>
                /// 背景颜色
                /// </summary>
                [Description("背景颜色")]
                [PropertyOrder(-195)]
                [SkinProperty(true, true)]
                public Color BackColor
                {
                    get
                    {
                        if (this.owner.GetSkinObjectSkinStateCore() && this.skinBackColor != Color.Empty)
                        {
                            return this.skinBackColor;
                        }

                        if (this.backColor != Color.Empty)
                        {
                            return this.backColor;
                        }

                        if (((Control)this.owner).Parent != null)
                        {
                            return ((Control)this.owner).Parent.BackColor;
                        }

                        return this.defaultBackColor;
                    }
                    set
                    {
                        if (this.backColor == value)
                            return;

                        this.backColor = value;
                        this.Invalidate();
                    }
                }
                private bool ShouldSerializeBackColor()
                {
                    return this.backColor != Color.Empty;
                }
                private void ResetBackColor()
                {
                    this.backColor = Color.Empty;
                    this.Invalidate();
                }

                private StateAppearanceObject unChecked;
                /// <summary>
                /// 未选中状态样式
                /// </summary>
                [Description("未选中状态样式")]
                [PropertyOrder(-116)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public StateAppearanceObject UnChecked
                {
                    get
                    {
                        if (this.unChecked == null)
                            this.unChecked = new StateAppearanceObject(this.owner, this
                                , SystemColors.ActiveCaption
                                , Color.Empty
                                , Color.Empty
                                , SystemColors.ControlText
                                , SystemColors.InactiveCaption
                                , Color.Empty
                                , Color.Empty
                                , SystemColors.ControlText
                                );
                        return this.unChecked;
                    }
                }

                private StateAppearanceObject indeterminate;
                /// <summary>
                /// 半选中状态样式
                /// </summary>
                [Description("半选中状态样式")]
                [PropertyOrder(-114)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public StateAppearanceObject Indeterminate
                {
                    get
                    {
                        if (this.indeterminate == null)
                            this.indeterminate = new StateAppearanceObject(this.owner, this
                                , SystemColors.ActiveCaption
                                , Color.Empty
                                , SystemColors.ActiveCaption
                                , SystemColors.ControlText
                                , SystemColors.InactiveCaption
                                , Color.Empty
                                , SystemColors.InactiveCaption
                                , SystemColors.ControlText
                                );
                        return this.indeterminate;
                    }
                }

                private StateAppearanceObject _checked;
                /// <summary>
                /// 已选中状态样式
                /// </summary>
                [Description("已选中状态样式")]
                [PropertyOrder(-112)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public StateAppearanceObject Checked
                {
                    get
                    {
                        if (this._checked == null)
                            this._checked = new StateAppearanceObject(this.owner, this
                                , SystemColors.ActiveCaption
                                , Color.Empty
                                , SystemColors.ActiveCaption
                                , SystemColors.ControlText
                                , SystemColors.InactiveCaption
                                , Color.Empty
                                , SystemColors.InactiveCaption
                                , SystemColors.ControlText
                                );
                        return this._checked;
                    }
                }

                #endregion

                public class StateAppearanceObject : AppearanceObjectBase
                {
                    internal StateAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderNormalColor, Color backNormalColor, Color foreNormalColor, Color textNormalColor, Color borderDisabledColor, Color backDisabledColor, Color foreDisabledColor, Color textDisabledColor) : base(owner, parent)
                    {
                        this.borderNormalColor = borderNormalColor;
                        this.backNormalColor = backNormalColor;
                        this.foreNormalColor = foreNormalColor;
                        this.textNormalColor = textNormalColor;
                        this.borderDisabledColor = borderDisabledColor;
                        this.backDisabledColor = backDisabledColor;
                        this.foreDisabledColor = foreDisabledColor;
                        this.textDisabledColor = textDisabledColor;
                    }

                    #region 属性

                    private Color borderNormalColor = Color.Empty;
                    private Color backNormalColor = Color.Empty;
                    private Color foreNormalColor = Color.Empty;
                    private Color textNormalColor = Color.Empty;
                    private ItemAppearanceObject normal;
                    /// <summary>
                    /// 正常状态
                    /// </summary>
                    [Description("正常状态")]
                    [PropertyOrder(-194)]
                    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                    [SkinProperty(true, false)]
                    public ItemAppearanceObject Normal
                    {
                        get
                        {
                            if (this.normal == null)
                                this.normal = new ItemAppearanceObject(this.owner, this, this.borderNormalColor, this.backNormalColor, this.foreNormalColor, this.textNormalColor);
                            return this.normal;
                        }
                    }

                    private Color borderDisabledColor = Color.Empty;
                    private Color backDisabledColor = Color.Empty;
                    private Color foreDisabledColor = Color.Empty;
                    private Color textDisabledColor = Color.Empty;
                    private ItemAppearanceObject disabled;
                    /// <summary>
                    /// 禁用状态
                    /// </summary>
                    [Description("禁用状态")]
                    [PropertyOrder(-190)]
                    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                    [SkinProperty(true, false)]
                    public ItemAppearanceObject Disabled
                    {
                        get
                        {
                            if (this.disabled == null)
                                this.disabled = new ItemAppearanceObject(this.owner, this, this.borderDisabledColor, this.backDisabledColor, this.foreDisabledColor, this.textDisabledColor);
                            return this.disabled;
                        }
                    }

                    #endregion

                    public class ItemAppearanceObject : AppearanceObjectBase
                    {
                        internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderColor, Color backColor, Color foreColor, Color textColor) : base(owner, parent)
                        {
                            this.defaultBoxBorderColor = borderColor;
                            this.defaultBoxBackColor = backColor;
                            this.defaultBoxForeColor = foreColor;
                            this.defaultTextColor = textColor;
                        }

                        #region 属性

                        private Color skinTextColor = Color.Empty;
                        private readonly Color defaultTextColor = Color.Empty;
                        private Color textColor = Color.Empty;
                        /// <summary>
                        /// 文本颜色
                        /// </summary>
                        [Description("文本颜色")]
                        [PropertyOrder(-194)]
                        [SkinProperty(true, false)]
                        public Color TextColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinTextColor;
                                }

                                if (this.textColor != Color.Empty)
                                {
                                    return this.textColor;
                                }

                                return this.defaultTextColor;
                            }
                            set
                            {
                                if (this.textColor == value)
                                    return;

                                this.textColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeTextColor()
                        {
                            return this.textColor != Color.Empty;
                        }
                        private void ResetTextColor()
                        {
                            this.textColor = Color.Empty;
                            this.Invalidate();
                        }

                        private Color skinBoxBorderColor = Color.Empty;
                        private readonly Color defaultBoxBorderColor = Color.Empty;
                        private Color boxBorderColor = Color.Empty;
                        /// <summary>
                        /// 复选框边框颜色
                        /// </summary>
                        [Description("复选框边框颜色")]
                        [PropertyOrder(-188)]
                        [SkinProperty(true, false)]
                        public Color BoxBorderColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinBoxBorderColor;
                                }

                                if (this.boxBorderColor != Color.Empty)
                                {
                                    return this.boxBorderColor;
                                }

                                return this.defaultBoxBorderColor;
                            }
                            set
                            {
                                if (this.boxBorderColor == value)
                                    return;

                                this.boxBorderColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeBoxBorderColor()
                        {
                            return this.boxBorderColor != Color.Empty;
                        }
                        private void ResetBoxBorderColor()
                        {
                            this.boxBorderColor = Color.Empty;
                            this.Invalidate();
                        }

                        private Color skinBoxBackColor = Color.Empty;
                        private readonly Color defaultBoxBackColor = Color.Empty;
                        private Color boxBackColor = Color.Empty;
                        /// <summary>
                        /// 复选框背景颜色
                        /// </summary>
                        [Description("复选框背景颜色")]
                        [PropertyOrder(-186)]
                        [SkinProperty(true, false)]
                        public Color BoxBackColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinBoxBackColor;
                                }

                                if (this.boxBackColor != Color.Empty)
                                {
                                    return this.boxBackColor;
                                }

                                return this.defaultBoxBackColor;
                            }
                            set
                            {
                                if (this.boxBackColor == value)
                                    return;

                                this.boxBackColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeBoxBackColor()
                        {
                            return this.boxBackColor != Color.Empty;
                        }
                        private void ResetBoxBackColor()
                        {
                            this.boxBackColor = Color.Empty;
                            this.Invalidate();
                        }

                        private Color skinBoxForeColor = Color.Empty;
                        private readonly Color defaultBoxForeColor = Color.Empty;
                        private Color boxForeColor = Color.Empty;
                        /// <summary>
                        /// 复选框前景颜色
                        /// </summary>
                        [Description("复选框前景颜色")]
                        [PropertyOrder(-185)]
                        [SkinProperty(true, false)]
                        public Color BoxForeColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinBoxForeColor;
                                }

                                if (this.boxForeColor != Color.Empty)
                                {
                                    return this.boxForeColor;
                                }

                                return this.defaultBoxForeColor;
                            }
                            set
                            {
                                if (this.boxForeColor == value)
                                    return;

                                this.boxForeColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeBoxForeColor()
                        {
                            return this.boxForeColor != Color.Empty;
                        }
                        private void ResetBoxForeColor()
                        {
                            this.boxForeColor = Color.Empty;
                            this.Invalidate();
                        }

                        internal ImageIndexer imageIndexer = new ImageIndexer();
                        /// <summary>
                        /// 复选框图片 
                        /// </summary>
                        [Description("复选框图片 ")]
                        [PropertyOrder(-182)]
                        [DefaultValue(null)]
                        [SkinProperty(false, false)]
                        public Image Image
                        {
                            get { return this.imageIndexer.Image; }
                            set
                            {
                                if (!this.imageIndexer.EqualImage(value))
                                {
                                    this.imageIndexer.Image = value;
                                    this.Invalidate();
                                }
                            }
                        }

                        /// <summary>
                        /// 复选框图片Index 
                        /// </summary>
                        [Description("复选框图片Index ")]
                        [PropertyOrder(-180)]
                        [DefaultValue(-1)]
                        [Localizable(true)]
                        [RefreshProperties(RefreshProperties.Repaint)]
                        [TypeConverter(typeof(ImageIndexConverter))]
                        [SkinProperty(false, false)]
                        public int ImageIndex
                        {
                            get { return this.imageIndexer.Index; }
                            set
                            {
                                if (!this.imageIndexer.EqualIndex(value))
                                {
                                    this.imageIndexer.Index = value;
                                    this.Invalidate();
                                }
                            }
                        }

                        /// <summary>
                        /// 复选框图片Key 
                        /// </summary>
                        [Description("复选框图片Key ")]
                        [PropertyOrder(-178)]
                        [DefaultValue("")]
                        [Localizable(true)]
                        [RefreshProperties(RefreshProperties.Repaint)]
                        [TypeConverter(typeof(ImageKeyConverter))]
                        [SkinProperty(false, false)]
                        public string ImageKey
                        {
                            get { return this.imageIndexer.Key; }
                            set
                            {
                                if (!this.imageIndexer.EqualKey(value))
                                {
                                    this.imageIndexer.Key = value;
                                    this.Invalidate();
                                }
                            }
                        }

                        #endregion

                    }

                }

            }

            public class ButtonPatternAppearanceObject : AppearanceObjectBase
            {
                internal ButtonPatternAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

                #region 属性

                private StateAppearanceObject unChecked;
                /// <summary>
                /// 未选中状态样式
                /// </summary>
                [Description("未选中状态样式")]
                [PropertyOrder(-196)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public StateAppearanceObject UnChecked
                {
                    get
                    {
                        if (this.unChecked == null)
                            this.unChecked = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                                );
                        return this.unChecked;
                    }
                }

                private StateAppearanceObject indeterminate;
                /// <summary>
                /// 半选中状态样式
                /// </summary>
                [Description("半选中状态样式")]
                [PropertyOrder(-194)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public StateAppearanceObject Indeterminate
                {
                    get
                    {
                        if (this.indeterminate == null)
                            this.indeterminate = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientInactiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                                );
                        return this.indeterminate;
                    }
                }

                private StateAppearanceObject _checked;
                /// <summary>
                /// 已选中状态样式
                /// </summary>
                [Description("已选中状态样式")]
                [PropertyOrder(-192)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public StateAppearanceObject Checked
                {
                    get
                    {
                        if (this._checked == null)
                            this._checked = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                                );
                        return this._checked;
                    }
                }

                #endregion

                public class StateAppearanceObject : AppearanceObjectBase
                {
                    internal StateAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderNormalColor, Color backNormalColor, Color textNormalColor, Color borderEnterColor, Color backEnterColor, Color textEnterColor, Color borderDisabledColor, Color backDisabledColor, Color textDisabledColor) : base(owner, parent)
                    {
                        this.borderNormalColor = borderNormalColor;
                        this.backNormalColor = backNormalColor;
                        this.textNormalColor = textNormalColor;
                        this.borderEnterColor = borderEnterColor;
                        this.backEnterColor = backEnterColor;
                        this.textEnterColor = textEnterColor;
                        this.borderDisabledColor = borderDisabledColor;
                        this.backDisabledColor = backDisabledColor;
                        this.textDisabledColor = textDisabledColor;
                    }

                    #region 属性

                    private Color borderNormalColor = Color.Empty;
                    private Color backNormalColor = Color.Empty;
                    private Color textNormalColor = Color.Empty;
                    private ItemAppearanceObject normal;
                    /// <summary>
                    /// 正常状态
                    /// </summary>
                    [Description("正常状态")]
                    [PropertyOrder(-194)]
                    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                    [SkinProperty(true, false)]
                    public ItemAppearanceObject Normal
                    {
                        get
                        {
                            if (this.normal == null)
                                this.normal = new ItemAppearanceObject(this.owner, this, this.borderNormalColor, this.backNormalColor, this.textNormalColor);
                            return this.normal;
                        }
                    }

                    private Color borderEnterColor = Color.Empty;
                    private Color backEnterColor = Color.Empty;
                    private Color textEnterColor = Color.Empty;
                    private ItemAppearanceObject enter;
                    /// <summary>
                    /// 鼠标进入状态
                    /// </summary>
                    [Description("鼠标进入状态")]
                    [PropertyOrder(-192)]
                    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                    [SkinProperty(true, false)]
                    public ItemAppearanceObject Enter
                    {
                        get
                        {
                            if (this.enter == null)
                                this.enter = new ItemAppearanceObject(this.owner, this, this.borderEnterColor, this.backEnterColor, this.textEnterColor);
                            return this.enter;
                        }
                    }

                    private Color borderDisabledColor = Color.Empty;
                    private Color backDisabledColor = Color.Empty;
                    private Color textDisabledColor = Color.Empty;
                    private ItemAppearanceObject disabled;
                    /// <summary>
                    /// 禁用状态
                    /// </summary>
                    [Description("禁用状态")]
                    [PropertyOrder(-190)]
                    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                    [SkinProperty(true, false)]
                    public ItemAppearanceObject Disabled
                    {
                        get
                        {
                            if (this.disabled == null)
                                this.disabled = new ItemAppearanceObject(this.owner, this, this.borderDisabledColor, this.backDisabledColor, this.textDisabledColor);
                            return this.disabled;
                        }
                    }

                    #endregion

                    public class ItemAppearanceObject : AppearanceObjectBase
                    {
                        internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderColor, Color backColor, Color textColor) : base(owner, parent)
                        {
                            this.defaultBorderColor = borderColor;
                            this.defaultBackColor = backColor;
                            this.defaultTextColor = textColor;
                        }

                        #region 属性

                        private Color skinBorderColor = Color.Empty;
                        private readonly Color defaultBorderColor = Color.Empty;
                        private Color borderColor = Color.Empty;
                        /// <summary>
                        /// 边框颜色
                        /// </summary>
                        [Description("边框颜色")]
                        [PropertyOrder(-159)]
                        [SkinProperty(true, false)]
                        public Color BorderColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinBorderColor;
                                }

                                if (this.borderColor != Color.Empty)
                                {
                                    return this.borderColor;
                                }

                                return this.defaultBorderColor;
                            }
                            set
                            {
                                if (this.borderColor == value)
                                    return;

                                this.borderColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeBorderColor()
                        {
                            return this.borderColor != Color.Empty;
                        }
                        private void ResetBorderColor()
                        {
                            this.borderColor = Color.Empty;
                            this.Invalidate();
                        }

                        private Color skinBackColor = Color.Empty;
                        private readonly Color defaultBackColor = Color.Empty;
                        private Color backColor = Color.Empty;
                        /// <summary>
                        /// 背景颜色
                        /// </summary>
                        [Description("背景颜色")]
                        [PropertyOrder(-158)]
                        [SkinProperty(true, false)]
                        public Color BackColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinBackColor;
                                }

                                if (this.backColor != Color.Empty)
                                {
                                    return this.backColor;
                                }

                                return this.defaultBackColor;
                            }
                            set
                            {
                                if (this.backColor == value)
                                    return;

                                this.backColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeBackColor()
                        {
                            return this.backColor != Color.Empty;
                        }
                        private void ResetBackColor()
                        {
                            this.backColor = Color.Empty;
                            this.Invalidate();
                        }

                        private Color skinTextColor = Color.Empty;
                        private readonly Color defaultTextColor = Color.Empty;
                        private Color textColor = Color.Empty;
                        /// <summary>
                        /// 文本颜色
                        /// </summary>
                        [Description("文本颜色")]
                        [PropertyOrder(-157)]
                        [SkinProperty(true, false)]
                        public Color TextColor
                        {
                            get
                            {
                                if (this.owner.GetSkinObjectSkinStateCore())
                                {
                                    return this.skinTextColor;
                                }

                                if (this.textColor != Color.Empty)
                                {
                                    return this.textColor;
                                }

                                return this.defaultTextColor;
                            }
                            set
                            {
                                if (this.textColor == value)
                                    return;

                                this.textColor = value;
                                this.Invalidate();
                            }
                        }
                        private bool ShouldSerializeTextColor()
                        {
                            return this.textColor != Color.Empty;
                        }
                        private void ResetTextColor()
                        {
                            this.textColor = Color.Empty;
                            this.Invalidate();
                        }

                        #endregion

                    }

                }

            }
        }

        #endregion

    }
}
